﻿using DBUtil.Generators;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DBUtil
{
    /// <summary>
    /// 支持多个数据库类型
    /// </summary>
    public static class DBFactory
    {
        private static ConcurrentDictionary<Type, IDBFactory<DBAccess>> dic_factorys = new ConcurrentDictionary<Type, IDBFactory<DBAccess>>();

        /// <summary>
        /// 添加数据库类型支持
        /// </summary>
        /// <typeparam name="T">特定数据库类型的工厂,比如:SqlServerDBFactory</typeparam>
        public static void AddDBSupport<T>() where T : IDBFactory<DBAccess>, new()
        {
            var type = typeof(T);
            var instance = new T();
            dic_factorys.GetOrAdd(type, instance);
        }

        /// <summary>
        /// 创建IDB对象
        /// </summary>
        /// <param name="DBType">数据库类型示例:SQLSERVER、ORACLE、MYSQL、SQLITE、ACCESS、POSTGRESQL</param>
        /// <param name="DBConn">
        /// <para>连接字符串示例:</para>
        /// <para>SQLSERVER:   Data Source=.;Initial Catalog=test;User ID=sa;Password=xx;</para>
        /// <para>ORACLE:   Data Source=ORCTest;Password=xx;User ID=sys;DBA Privilege=SYSDBA;</para>
        /// <para>MYSQL:   Data Source=localhost;Initial Catalog=test;User ID=root;Password=xxxx;</para>
        /// <para>POSTGRESQL:   Server=localhost;Port=5432;UserId=postgres;Password=xxxx;Database=test</para>
        /// <para>ACCESS:   Provider=Microsoft.Jet.OLEDB.4.0;Data Source=G:\work\test.mdb;</para>
        /// <para>ACCESS:   Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Administrator\Desktop\test.accdb;</para>
        /// <para>SQLITE:   Data Source=f:\test.db;</para>
        /// </param>
        /// <param name="Settings">使用的设置(默认为DBSettings.GlobalSetting)</param>
        public static DBAccess CreateDB(string DBType, string DBConn, DBSettings Settings = null)
        {
            if (Settings == null) Settings = DBSettings.Default.Clone() as DBSettings;
            DBAccess db = null;
            foreach (var factory in dic_factorys.Values)
            {
                db = factory.CreateDB(DBType, DBConn, Settings);
                if (db != null) return db;
            }
            if (db == null) throw new Exception($"未找到支持的数据库类型:{DBType},请下载对应的nuget包,并调用[DBFactory.AddDBSupport<MySqlDBFactory>()]");
            return db;
        }
    }
}
